﻿#include "clientdisktcpsocket.h"
#include <QMutex>
#include "utils.h"
#include <QMessageBox>
#include "operatewidget.h"
#include "tinydiskclient.h"
#include "protocol.h"
#include "addfrienddialog.h"
#include "filewidget.h"

ClientDiskTcpSocket::ClientDiskTcpSocket(QObject *parent)
    : QTcpSocket{parent}
{
    initMember();
    // 连接服务器
    slot_ReConnect();
    if(this->state() != QAbstractSocket::ConnectedState){
        MYLOG<<"连接服务器中...";
        reConnectTimer->start(6000);
    }
}

ClientDiskTcpSocket * ClientDiskTcpSocket::getInstance()
{
    static QMutex mutex;
    static QScopedPointer<ClientDiskTcpSocket> inst;
    if (Q_UNLIKELY(!inst)) {
        mutex.lock();
        if (!inst) {
            inst.reset(new ClientDiskTcpSocket);
        }
        mutex.unlock();
    }
    return inst.data();
}

void ClientDiskTcpSocket::initMember()
{
    connect(this,SIGNAL(connected()), this, SLOT(slot_Connected()));
    connect(this,SIGNAL(disconnected()),this,SLOT(slot_DisConnected()));
    connect(this,SIGNAL(readyRead()),this,SLOT(slot_RecvMsg()));

    reConnectTimer = new QTimer();
    connect(reConnectTimer,&QTimer::timeout, this, &ClientDiskTcpSocket::slot_ReConnect);
}

void ClientDiskTcpSocket::slot_Connected()
{
    TinyDiskClient::getInstance()->handle_ConnectToHost(true);
    reConnectTimer->stop();
}

void ClientDiskTcpSocket::slot_DisConnected()
{
    TinyDiskClient::getInstance()->handle_ConnectToHost(false);
    TinyDiskClient::getInstance()->handle_disconnectHost();

    reConnectTimer->start(6000);
}

void ClientDiskTcpSocket::slot_ReConnect()
{
    if(this->state() == QAbstractSocket::UnconnectedState){
        MYLOG<<"连接服务器中...";
        this->connectToHost("127.0.0.1", 8888);
        // this->connectToHost(m_strIP, m_usPort);
    }
}

void ClientDiskTcpSocket::slot_RecvMsg()
{
    uint uiPDULen = 0;
    uint uiMsgLen = 0;
    this->read((char* )&uiPDULen, sizeof(uint));
    uiMsgLen = uiPDULen - sizeof(PDU);
    PDU* pduRecv = mkPDU(uiMsgLen);
    pduRecv->uiPDULen = uiPDULen;
    this->read((char*)pduRecv + sizeof(uint), uiPDULen - sizeof(uint));
    switch (pduRecv->uiMsgType) {
    case ENUM_MSG_TYPE_REGIST_RESPOND:
        TinyDiskClient::getInstance()->handle_Regist_Respond(pduRecv);
        break;
    case ENUM_MSG_TYPE_LOGIN_RESPOND:
        TinyDiskClient::getInstance()->handle_Login_Respond(pduRecv);
        break;
    case ENUM_MSG_TYPE_SEARCH_USER_RESPOND:
        AddFriendDialog::getInstance()->handleSearch(pduRecv);
        break;
    case ENUM_MSG_TYPE_ADD_FRIEND_REQUEST:
        OperateWidget::getInstance().handleAddFriendRequst(pduRecv);
        break;
    case ENUM_MSG_TYPE_ADD_FRIEND_RESPOND:
        AddFriendDialog::getInstance()->handleAddFriendRespond(pduRecv);
        break;
    case ENUM_MSG_TYPE_ADD_FRIEND_AGREE:
        OperateWidget::getInstance().handleAddFriendAgeree(pduRecv);
        break;
    case ENUM_MSG_TYPE_ADD_FRIEND_REJECT:
        OperateWidget::getInstance().handleAddFriendRefuse(pduRecv);
        break;
    case ENUM_MSG_TYPE_CREATE_DIR_RESPOND:
        OperateWidget::getInstance().getFileWidget()->handleCreateDirRespond(
            pduRecv);
        break;
    case ENUM_MSG_TYPE_FLUSH_DIR_RESPOND:
        OperateWidget::getInstance().getFileWidget()->handleUpdateFileList(
            pduRecv);
        break;
    case ENUM_MSG_TYPE_DELETE_FILE_RESPOND:
        OperateWidget::getInstance().getFileWidget()->handleDeleteFileRespond(
            pduRecv);
        break;
    case ENUM_MSG_TYPE_RENAME_FILE_RESPOND:
        OperateWidget::getInstance().getFileWidget()->handleRenameFile(pduRecv);
        break;
    case ENUM_MSG_TYPE_ENTRY_DIR_RESPOND:
        OperateWidget::getInstance().getFileWidget()->handleEnterDir(pduRecv);
        break;
    case ENUM_MSG_TYPE_UPLOAD_FILE_RESPOND:
        OperateWidget::getInstance().getFileWidget()->handleUploadFile(pduRecv);
        break;
    case ENUM_MSG_TYPE_UPLOADED_FILE_RESPOND:
        OperateWidget::getInstance().getFileWidget()->handleUploadedFile(pduRecv);
        break;
    }
}

void ClientDiskTcpSocket::loadConfig()
{
    QFile file(":/client.config");
    if(file.open(QFile::ReadOnly)){
        QByteArray baData = file.readAll();
        QString strData = QString(baData).simplified();
        QStringList strDataList = strData.split(" ");
        m_strIP = strDataList[0];
        bool ok;
        m_usPort = strDataList[1].toUShort(&ok);
        if(!ok){
            MYLOG<<"Failed to parse configuration file!";
            // QMessageBox::critical(this,"Parse Config","Failed to parse configuration file!");
        }
        file.close();
    }else{
        MYLOG<<"Open config file failed!";
        // QMessageBox::critical(this,"Open Config","Open config file failed!");
    }
}

QString ClientDiskTcpSocket::usrName() const
{
    return m_usrName;
}

void ClientDiskTcpSocket::setUsrName(const QString &newUsrName)
{
    m_usrName = newUsrName;
}

QString ClientDiskTcpSocket::curPath()
{
    return m_strCurPath;
}

void ClientDiskTcpSocket::setStrCurPath(const QString &newStrCurPath)
{
    m_strCurPath = newStrCurPath;
}
